package top.cluski.feieprint.api.youzan;

import cn.hutool.core.util.StrUtil;
import com.dtflys.forest.Forest;
import com.dtflys.forest.utils.TypeReference;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import top.cluski.feieprint.api.youzan.domain.dto.ConfirmShipDTO;
import top.cluski.feieprint.api.youzan.entity.*;
import top.cluski.feieprint.config.YouzanConfig;

@Component
@Slf4j
public class YouzanApi {
    @Resource
    YouzanConfig youzanConfig;

    YouzanToken youzanToken;

    public String getToken() {
        if (youzanToken == null || youzanToken.expires < System.currentTimeMillis()) {
            TokenRespEntity tokenRespEntity = Forest.post("https://open.youzanyun.com/auth/token")
                    .contentTypeJson()
                    .addBody("client_id", youzanConfig.getClientId())
                    .addBody("client_secret", youzanConfig.getClientSecret())
                    .addBody("authorize_type", "silent")
                    .addBody("grant_id", "45706229")
                    .addBody("refresh", "false")
                    .execute(TokenRespEntity.class);
            if (!tokenRespEntity.getSuccess()) {
                log.error("获取有赞access_token失败 code={} message={}", tokenRespEntity.getCode(), tokenRespEntity.getMessage());
                throw new RuntimeException("获取有赞access_token失败");
            }

            this.youzanToken = new YouzanToken(tokenRespEntity.getData().getAccessToken(), tokenRespEntity.getData().getExpires());
        }
        return youzanToken.getToken();
    }

    public TradeOrderRespEntity.DataResponse getTradeOrder(String keywords) {
        TradeOrderRespEntity tradeOrderRespEntity = Forest.post("https://open.youzanyun.com/api/youzan.trades.sold.get/4.0.4?access_token=" + getToken())
                .addBody("keywords", keywords)
                .execute(TradeOrderRespEntity.class);
        if (!tradeOrderRespEntity.isSuccess()) {
            log.error("获取有赞订单失败 keywords={} code={} message={}", keywords, tradeOrderRespEntity.getCode(), tradeOrderRespEntity.getMessage());
            throw new RuntimeException("获取有赞订单失败");
        }

        return tradeOrderRespEntity.getData();
    }

    public void confirmShip(String tid) {
        CommonRespEntity commonRespEntity = Forest.post("https://open.youzanyun.com/api/youzan.logistics.online.confirm/3.0.0?access_token=" + getToken())
                .addBody("tid", tid)
                .addBody("is_no_express", 1)
                .execute(CommonRespEntity.class);
        if (shipFailed(commonRespEntity)) {
            log.error("有赞订单发货失败 tid={} resp={}", tid, commonRespEntity);
            throw new RuntimeException("有赞订单发货失败");
        }
    }

    public void confirmShipWithExpress(ConfirmShipDTO confirmShipDTO) {
        CommonRespEntity commonRespEntity = Forest.post("https://open.youzanyun.com/api/youzan.logistics.online.confirm/3.0.0?access_token=" + getToken())
                .addBody(confirmShipDTO)
                .execute(CommonRespEntity.class);
        if (shipFailed(commonRespEntity)) {
            log.error("有赞订单发货失败 dto={} resp={}", confirmShipDTO, commonRespEntity);
            throw new RuntimeException("有赞订单发货失败");
        }
    }

    private boolean shipFailed(CommonRespEntity commonRespEntity) {
        if (commonRespEntity.isSuccess()) {
            return false;
        }
        return !StrUtil.contains(commonRespEntity.getMessage(), "订单没有可发货的商品");
    }

    public String decrypt(String encryptData) {
        DecryptRespEntity decryptRespEntity = Forest.post("https://open.youzanyun.com/api/youzan.cloud.secret.decrypt.single/1.0.0?access_token=" + getToken())
                .addBody("source", encryptData)
                .execute(DecryptRespEntity.class);
        if (!decryptRespEntity.isSuccess()) {
            log.error("有赞解密接口失败 resp={}", decryptRespEntity);
            throw new RuntimeException("有赞解密接口失败");
        }

        return decryptRespEntity.getData();
    }

    public TradeOrderRespEntity.FullOrderInfo getOrderDetail(String tid) {
        OrderDetailRespEntity orderDetailRespEntity = Forest.post("https://open.youzanyun.com/api/youzan.trade.get/4.0.2?access_token=" + getToken())
                .addBody("tid", tid)
                .execute(OrderDetailRespEntity.class);

        if (!orderDetailRespEntity.isSuccess()) {
            log.error("有赞获取订单详细信息失败 resp={}", orderDetailRespEntity);
            throw new RuntimeException("有赞获取订单详细信息失败");
        }

        return orderDetailRespEntity.getData().getFull_order_info();
    }

    public SpuRespEntity getSpu(String spuCode) {
        YouzanRespEntity<SpuRespEntity> spuRespEntity = Forest.post("https://open.youzanyun.com/api/youzan.retail.open.spu.get/3.0.0?access_token=" + getToken())
                .addBody("spu_code", spuCode)
                .execute(new TypeReference<>() {
                });
        if (!spuRespEntity.isSuccess()) {
            log.error("有赞获取spu详情失败 resp={}", spuRespEntity);
            throw new RuntimeException("有赞获取spu详情失败");
        }

        return spuRespEntity.getData();
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class YouzanToken {
        String token;
        Long expires;
    }

}
